﻿using CommunityToolkit.Mvvm.ComponentModel;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Configuration;
using System.Data;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using WpfDemo.IRepository;
using WpfDemo.IRepository.Sys;
using WpfDemo.Models.Context;
using WpfDemo.Repository;
using WpfDemo.Repository.Sys;
using WpfDemo.View;
using WpfDemo.ViewModel;
using WpfDemo.ViewModel.Sys;

namespace WpfDemo
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        public static IServiceProvider ServiceProvider { get; private set; }
        public App()
        {
            var host = Host.CreateDefaultBuilder()
                .ConfigureServices(ConfigureServices)
                .Build();
            ServiceProvider = host.Services;
        }
        protected override void OnStartup(StartupEventArgs e)
        {
            var window = ServiceProvider.GetRequiredService<View.LoginView>();
            window.Show();
            base.OnStartup(e);
        }

        private void ConfigureServices(HostBuilderContext hostBuilderContext, IServiceCollection services)
        {

           


            #region 加入视图页面和视图模型
            //使用动态方式加入
            var types = System.Reflection.Assembly.GetExecutingAssembly().DefinedTypes.Select(type => type.AsType());

            ////视图页面对象 typeof(Page)，使用单件模式，每次请求都是一样的页面
            var viewPageBaseType = typeof(Page);
            var pageClasses = types.Where(x => x != viewPageBaseType && viewPageBaseType.IsAssignableFrom(x))
                                  .Where(x => x.IsClass && !x.IsAbstract).ToList();
            foreach (var page in pageClasses)
            {
                services.AddSingleton(page);
            }

            var UserControlType = typeof(UserControl);
            var UserControls = types.Where(x => x != UserControlType && UserControlType.IsAssignableFrom(x))
                                  .Where(x => x.IsClass && !x.IsAbstract).ToList();
            foreach (var page in UserControls)
            {
                services.AddSingleton(page);
            }

            //视图模型对象 typeof(ObservableObject)
            var viewModelBaseType = typeof(ObservableObject);
            var viewModels = types.Where(x => x != viewModelBaseType && viewModelBaseType.IsAssignableFrom(x))
                                  .Where(x => x.IsClass && !x.IsAbstract).ToList();
            foreach (var view in viewModels)
            {
                services.AddSingleton(view);
            }

            //窗口对象,使用 Transient 模式，每次请求都是一个新的窗体
            var windowBaseType = typeof(Window);
            var windowClasses = types.Where(x => x != windowBaseType && windowBaseType.IsAssignableFrom(x))
                                  .Where(x => x.IsClass && !x.IsAbstract).ToList();
            foreach (var window in windowClasses)
            {
                services.AddSingleton(window);
            }
            #endregion

            var assembly = Assembly.GetExecutingAssembly().GetReferencedAssemblies()
               .Where(a => a.Name.StartsWith("WpfDemo.IRepository"))
               .Select(a => Assembly.Load(a))
               .FirstOrDefault();
            var assRepo = Assembly.GetExecutingAssembly().GetReferencedAssemblies()
              .Where(a => a.Name.StartsWith("WpfDemo.Repository"))
              .Select(a => Assembly.Load(a))
              .FirstOrDefault();

            var serviceTypes = assembly.GetTypes().Where(x => x.Name.EndsWith("Repository") && x.IsInterface).ToList();
            var implementationTypes = assRepo.GetTypes().Where(x => x.Name.EndsWith("Repository") && x.IsClass).ToList();

            //遍历IAService接口
            foreach (var serviceType in serviceTypes)
            {
                //Linq查询结尾是ServiceImpl的类
                //例如AServiceImpl，比较它去掉Impl，首字母加上I，判断它是否和接口名IAService相等
                var implementationType = implementationTypes.FirstOrDefault(t =>
                    serviceType.Name == "I" + t.Name);

                if (implementationType != null)
                {
                    //Console.WriteLine(serviceType.ToString());
                    //Console.WriteLine(implementationType.ToString());
                    services.AddScoped(serviceType, implementationType);
                }
            }


            //services.AddSingleton<IStudentService, StudentService>();
            //services.AddSingleton<MainWindow>();
            //services.AddSingleton<LoginView>();
            //services.AddSingleton<MainWindowViewModel>();
            //services.AddSingleton<LoginViewModel>();
            //services.AddSingleton<IUserRepository, UserRepository>();
            //services.AddSingleton<View.Sys.User.Index>();
            //services.AddSingleton<UserViewModel>();
            services.AddTransient(typeof(IBaseRepository<>), typeof(BaseRepository<>));
            services.AddDbContext<EfContext>(options => options.UseSqlite("Data Source=db/weight.db"));

        }
    }

}
